﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace CPPEI.Coolzon.UI.Script
{
    /// <summary>
    /// 用于供脚本访问组件的类
    /// </summary>
    public class SceneScriptObject
    {
        private WeakReference _part;
        private string _sceneName;
        private string _appType;

        /// <summary>
        /// 访问网络的对象，用于发送网络消息
        /// </summary>
        public SceneNetScriptObject net { get; 
            private set;
        }

        public object getNet()
        {
            return new SceneNetScriptObject("S0");
        }

        public SceneScriptObject(ScenePart part)
        {
            _sceneName = part.Name;
            _part = new WeakReference(part);
            _appType = PartContext.AppType;
            this.net = new SceneNetScriptObject(part.Name);
        }

        public string getAppType()
        {
            return _appType;
        }

        /// <summary>
        /// 设置组件的属性值
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="value"></param>
        public void setPropertyXmlString(string propertyName, object value)
        {
            XProperty.XPropertyDescription description = XPropertyUtility.GetXPropertyDescription(_part, propertyName);
            if (description != null)
            {
                XProperty.Converters.ConvertContext context = new XProperty.Converters.ConvertContext();
                Coolzon.Metadata.ValueNode valueNode = Coolzon.Metadata.ValueNode.Parse(Convert.ToString(value));
                XPropertyUtility.SetXPropertyValue(context, _part, description, valueNode);
            }
        }

        /// <summary>
        /// 获取组件的属性值
        /// </summary>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public object getPropertyXmlString(string propertyName)
        {
            XProperty.XPropertyDescription description = XPropertyUtility.GetXPropertyDescription(_part, propertyName);
            if (description != null)
            {
                XProperty.Converters.ConvertContext context = new XProperty.Converters.ConvertContext();
                return XPropertyUtility.GetXPropertyValue(context, _part, description);
            }
            return null;
        }

        /// <summary>
        /// 获取组件实例
        /// </summary>
        /// <param name="partName"></param>
        /// <returns></returns>
        public object getPart(string partName)
        {
            ScenePart scene = this._part.Target as ScenePart;
            if (scene == null)
            {
                return null;
            }
            UI.Part part = scene.GetChildPart(partName, true);
            if (part != null)
            {
                return part.GetScriptObj();
            }
            return null;
        }

        /// <summary>
        /// 发送鼠标按下事件
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void mouseLBDown(double x, double y)
        {
            ScenePart scene = this._part.Target as ScenePart;
            if (scene == null)
            {
                return;
            }
            UI.Part part = scene.GetPartAtPoint(typeof(Part), new Point(x, y), scene);
            if (part != null)
            {
                CPPEI.Coolzon.UI.Event.SceneMouseEvent @event = new Event.SceneMouseEvent();
                @event.MouseEventType = MouseEventType.MouseLeftDown.Name;
                @event.SceneName = scene.Name;
                @event.PartName = part.Name;
                @event.Point = new Point(x, y);
                Common.EventBus.Instance.Publish(@event);
            }
        }

        /// <summary>
        /// [2017新增]主要提供给WebView使用
        /// 发送事件
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="dataString"></param>
        public void netEventSend(string eventName, string dataString)
        {
            CPPEI.Coolzon.Event.NCL.NCLSendScriptNetEventEvent @event = new Coolzon.Event.NCL.NCLSendScriptNetEventEvent(_sceneName, eventName, dataString);
            CPPEI.Coolzon.Event.NCL.NCLEventBus.PublishAsync(@event);
        }

        /// <summary>
        /// 启动定时器
        /// </summary>
        /// <param name="interval"></param>
        /// <param name="funcName"></param>
        public void startTimer(double interval, string funcName)
        {
            ScenePart scene = this._part.Target as ScenePart;
            if (scene == null)
            {
                return;
            }
            scene.StartTimer(interval, funcName);
        }
    }

    public class SceneNetScriptObject
    {
        /// <summary>
        /// 场景名称
        /// </summary>
        private string _sceneName;

        /// <summary>
        /// 场景名称
        /// </summary>
        /// <param name="sceneName"></param>
        public SceneNetScriptObject(string sceneName)
        {
            _sceneName = sceneName;
        }

        /// <summary>
        /// 设置组件的属性值,此命令会发送到服务器，然后转送给其他客户端
        /// </summary>
        /// <param name="partName">组件名称</param>
        /// <param name="propertyName">属性名称</param>
        /// <param name="value">配置信息</param>
        public void setPropertyXmlString(string partName, string propertyName, string xmlString)
        {
            CPPEI.Coolzon.UI.Event.SetPropertyXmlStringEvent @event = new Event.SetPropertyXmlStringEvent();
            @event.SceneName = this._sceneName;
            @event.PartName = partName;
            @event.PropertyName = propertyName;
            @event.XmlString = xmlString;
            Common.EventBus.Instance.Publish(@event);
        }

        /// <summary>
        /// 发送脚本网络事件
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="dataString"></param>
        public void sendNetEvent(string eventName, string dataString)
        {
            CPPEI.Coolzon.Event.NCL.NCLSendScriptNetEventEvent @event = new Coolzon.Event.NCL.NCLSendScriptNetEventEvent(_sceneName, eventName, dataString);
            CPPEI.Coolzon.Event.NCL.NCLEventBus.PublishAsync(@event);
        }
    }
}
